﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Transactions;
using BaseLinQ.DataContex;
using Core;
using RBAC;

namespace Module
{
    public class VaiTroLogic
    {
        static string strConnectionString = ConfigurationSettings.AppSettings["ConnectString"];
        RBACDataContext db = null;
        public List<tbl_VaiTro> lstMenu = null;
        public List<tbl_VaiTro> lstMenuTmp = null;

        public DataTable GetListPaging( string strSort, string strDir, string strFilter, string NguoiDungID)
        {
            DataTable dtbl = null;
            DataSet dts = null;
            List<object> lstNhatKyVaoRa = new List<object>();
            int intTotal = 0;
            try
            {
                SqlParameter[] commandParameter = null;
                commandParameter = new SqlParameter[4];
                
                commandParameter[0] = new SqlParameter();
                commandParameter[0].ParameterName = "@filter";
                commandParameter[0].Value = strFilter;
                commandParameter[1] = new SqlParameter();
                commandParameter[1].ParameterName = "@sort";
                commandParameter[1].Value = strSort;
                commandParameter[2] = new SqlParameter();
                commandParameter[2].ParameterName = "@dir";
                commandParameter[2].Value = strDir;
                commandParameter[3] = new SqlParameter();
                commandParameter[3].ParameterName = "@NguoiDungID";
                commandParameter[3].Value = NguoiDungID;

                if (commandParameter != null)
                {
                    dts = SqlHelper.ExecuteDataset(strConnectionString, "sp_VaiTro_Select", commandParameter);
                    if (dts != null)
                    {
                        if (dts.Tables.Count > 0)
                        {
                            if (dts.Tables[0].Rows.Count > 0)
                            {
                                intTotal = int.Parse("0" + dts.Tables[0].Rows[0]["Total"].ToString());
                                dtbl = dts.Tables[0];
                                dts = null;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                
            }
            return dtbl;
        }

        /// <summary>
        /// Lay danh sach 
        /// </summary>
        /// <returns></returns>
        public List<tbl_VaiTro> GetList()
        {
            List<tbl_VaiTro> lstRes = null;
            db = new RBACDataContext(strConnectionString);
            try
            {
                lstRes = (from m in db.tbl_VaiTros
                          where m.bKichHoat == true
                          select m).ToList<tbl_VaiTro>();
            }
            catch (Exception ex)
            {
               
            }
            db = null;
            return lstRes;
        }

        /// <summary>
        /// Lay danh sach 
        /// </summary>
        /// <returns></returns>
        public List<tbl_VaiTro> GetListByNguoiDungID(long _lngNguoiDungID, long _lngDonViID)
        {
            List<tbl_VaiTro> lstRes = null;
            db = new RBACDataContext(strConnectionString);
            NguoiDungLogic logicND = new NguoiDungLogic();
            try
            {
                tbl_NguoiDung objND = (from n in db.tbl_NguoiDungs
                                       where n.bKichHoat == true
                                       && n.pk_iNguoiDungID == logicND.GetByID(_lngNguoiDungID).fk_iNguoiTaoID
                                       select n).FirstOrDefault<tbl_NguoiDung>();

                if (objND != null)
                {
                    lstRes = (from m in db.tbl_VaiTros
                              where m.bKichHoat == true
                              && ((m.fk_iNguoiTaoID == _lngNguoiDungID) || (m.bDungChung == true && m.fk_iNguoiTaoID == objND.pk_iNguoiDungID))
                              select m).ToList<tbl_VaiTro>();

                }
                else
                {
                    lstRes = (from m in db.tbl_VaiTros
                              where m.bKichHoat == true
                              && m.fk_iNguoiTaoID == _lngNguoiDungID
                              select m).ToList<tbl_VaiTro>();
                }
            }

            catch (Exception ex)
            {
                
            }
            // Gán những vai trò mà ng dùng đc phân cho.
            var objVTNDDV = from b in db.tbl_VaiTroNguoiDungDonVis
                            where b.bKichHoat == true
                            && b.fk_iDonViID == _lngDonViID
                            && b.fk_iNguoiDungID == _lngNguoiDungID
                            select b;
            if (objVTNDDV != null)
            {
                foreach (tbl_VaiTroNguoiDungDonVi m in objVTNDDV)
                {
                    tbl_VaiTro objVT = (from c in db.tbl_VaiTros
                                        where c.bKichHoat == true
                                        && c.pk_iVaiTroID == m.fk_iVaiTroID
                                        && c.bKichHoat == true
                                        && c.bDungChung == false
                                        select c).FirstOrDefault<tbl_VaiTro>();
                    if (objVT != null)
                    {
                        lstRes.Add(objVT);
                    }
                }
            }
            lstRes = lstRes.OrderBy(x => x.pk_iVaiTroID).ToList<tbl_VaiTro>();
            long check = 0;
            List<tbl_VaiTro> reList = new List<tbl_VaiTro>();
            foreach (tbl_VaiTro vt in lstRes)
            {
                if (vt.pk_iVaiTroID != check)
                {
                    reList.Add(vt);
                    check = vt.pk_iVaiTroID;
                }
            }
            db = null;
            return reList;
        }

        /// <summary>
        /// Lấy danh sách các vai trò theo ID của người dùng được gán
        /// </summary>
        /// <param name="_lngNguoiDungID"></param>
        /// <returns></returns>
        public List<tbl_VaiTro> GetListByNguoiDungDuocGanID(long _lngNguoiDungID)
        {
            List<tbl_VaiTro> lstRes = null;
            db = new RBACDataContext(strConnectionString);
            try
            {
                lstRes = (from m in db.tbl_VaiTros
                          from pq in db.tbl_VaiTroNguoiDungDonVis
                          where m.bKichHoat == true
                          && pq.bKichHoat == true
                          && pq.fk_iNguoiDungID == _lngNguoiDungID
                          && m.pk_iVaiTroID == pq.fk_iVaiTroID
                          select m).Distinct<tbl_VaiTro>().ToList<tbl_VaiTro>();
            }
            catch (Exception ex)
            {
                
            }
            db = null;
            return lstRes;
        }

        /// <summary>
        /// Lấy  theo ID
        /// </summary>
        /// <param name="_lngVaiTroID"></param>
        /// <returns></returns>
        public tbl_VaiTro GetByID(long _lngVaiTroID)
        {
            tbl_VaiTro objRes = null;
            db = new RBACDataContext(strConnectionString);
            try
            {
                objRes = (from m in db.tbl_VaiTros
                          where m.bKichHoat == true
                          && m.pk_iVaiTroID == _lngVaiTroID
                          select m).FirstOrDefault<tbl_VaiTro>();
            }
            catch (Exception ex)
            {
            }
            return objRes;
        }

        /// <summary>
        /// Lấy thao mã
        /// </summary>
        /// <param name="_strTenVaiTro"></param>
        /// <returns></returns>
        public tbl_VaiTro GetByName(string _strTenVaiTro)
        {
            tbl_VaiTro objRes = null;
            db = new RBACDataContext(strConnectionString);
            try
            {
                objRes = (from m in db.tbl_VaiTros
                          where m.bKichHoat == true
                          && m.sTenVaiTro == _strTenVaiTro
                          select m).FirstOrDefault<tbl_VaiTro>();
            }
            catch (Exception ex)
            {
                
            }
            return objRes;
        }

        /// <summary>
        /// Them moi
        /// </summary>
        /// <param name="_objVaiTro"></param>
        /// <returns></returns>
        public bool Insert(tbl_VaiTro _objVaiTro, Dictionary<int, bool> _dicQuyen)
        {
            bool blnFalse = false;
            db = new RBACDataContext(strConnectionString);
            try
            {
                _objVaiTro.dNgayTao = DateTime.Now;
                _objVaiTro.dNgayCapNhat = DateTime.Now;
                db.tbl_VaiTros.InsertOnSubmit(_objVaiTro);
                db.SubmitChanges();
                blnFalse = true;
                //Cập nhật danh sách quyền
                UpdateDanhSachQuyen(_objVaiTro.pk_iVaiTroID, _dicQuyen);
            }
            catch (Exception ex)
            {
                
            }
            db = null;
            return blnFalse;
        }

        /// <summary>
        /// Update sPath cho vai tro tao moi
        /// </summary>
        /// <param name="_objVaiTro"></param>
        public void UpdateVaitrosPath(tbl_VaiTro _objVaiTro)
        {
            db = new RBACDataContext(strConnectionString);
            tbl_VaiTro objVaiTro = (from m in db.tbl_VaiTros
                                    where m.pk_iVaiTroID == _objVaiTro.pk_iVaiTroID
                                    select m).FirstOrDefault<tbl_VaiTro>();
            objVaiTro.sPath = _objVaiTro.sPath;
            db.SubmitChanges();
            db = null;
        }


        //Check trùng tên vai trò
        public bool CheckTrungTenVT(string _sTenVaiTro, long _idDonVi)
        {
            bool check = true;
            db = new RBACDataContext(strConnectionString);

            tbl_VaiTro objVT = (from m in db.tbl_VaiTros
                                where m.bKichHoat == true
                                && m.fk_iDonViID == _idDonVi
                                && m.sTenVaiTro == _sTenVaiTro
                                select m).FirstOrDefault<tbl_VaiTro>();
            if (objVT != null)
            {
                check = false;
            }
            return check;
        }
        ////Check trùng quyền
        public bool CheckTrungQuyen(Dictionary<int, bool> _dicQuyen, long _idDonVi)
        {
            bool check = true;
            db = new RBACDataContext(strConnectionString);
            int No = _dicQuyen.Count;


            var objTong = from m in db.tbl_VaiTros
                          where m.bKichHoat == true
                          && m.fk_iDonViID == _idDonVi
                          select m;
            foreach (tbl_VaiTro sVaitro in objTong)
            {
                if (GetListCheckedQuyen(sVaitro.pk_iVaiTroID).Count == No)
                {
                    List<long> sQuyen = GetListCheckedQuyen(sVaitro.pk_iVaiTroID);
                    int ct = 0;
                    foreach (int sMa in sQuyen)
                    {

                        foreach (KeyValuePair<int, bool> sMaQuyen in _dicQuyen)
                        {
                            //ct = 0;
                            if (sMaQuyen.Key == sMa)
                            {
                                ct += 1;
                                break;
                            }

                        }
                        if (ct == No)
                        {
                            check = false;
                            break;
                        }
                    }
                    if (check == false)
                    {
                        break;
                    }
                }
            }

            return check;
        }
        /////
        /// <summary>
        /// Them moi
        /// </summary>
        /// <param name="_objVaiTro"></param>
        /// <returns></returns>
        public bool UpdateInfo(tbl_VaiTro _objVaiTro, Dictionary<int, bool> _dicQuyen)
        {
            bool blnFalse = false;
            db = new RBACDataContext(strConnectionString);
            tbl_VaiTro objVaiTroOld = (from m in db.tbl_VaiTros
                                       where m.pk_iVaiTroID == _objVaiTro.pk_iVaiTroID
                                       select m).FirstOrDefault<tbl_VaiTro>();
            try
            {
                objVaiTroOld.sTenVaiTro = _objVaiTro.sTenVaiTro;
                objVaiTroOld.sGhiChu = _objVaiTro.sGhiChu;
                objVaiTroOld.fk_iDonViID = _objVaiTro.fk_iDonViID;
                objVaiTroOld.fk_iNguoiCapNhatID = _objVaiTro.fk_iNguoiCapNhatID;
                objVaiTroOld.bDungChung = _objVaiTro.bDungChung;
                objVaiTroOld.dNgayCapNhat = DateTime.Now;
                db.SubmitChanges();
                blnFalse = true;
                //Cập nhật danh sách quyền
                UpdateDanhSachQuyen(_objVaiTro.pk_iVaiTroID, _dicQuyen);
            }
            catch (Exception ex)
            {
                
            }
            db = null;
            return blnFalse;
        }
        /// <summary>
        /// Cap nhat thong tin 
        /// </summary>
        /// <param name="_objVaiTroNew"></param>
        /// <returns></returns>
        public bool Update(tbl_VaiTro _objVaiTroNew, Dictionary<int, bool> _dicQuyen)
        {
            bool blnRes = false;
            db = new RBACDataContext(strConnectionString);
            try
            {
                tbl_VaiTro objVaiTroOld = (from m in db.tbl_VaiTros
                                           where m.pk_iVaiTroID == _objVaiTroNew.pk_iVaiTroID
                                           select m).FirstOrDefault<tbl_VaiTro>();
                if (objVaiTroOld != null && objVaiTroOld.pk_iVaiTroID > 0)
                {
                    objVaiTroOld.sTenVaiTro = _objVaiTroNew.sTenVaiTro;
                    objVaiTroOld.sGhiChu = _objVaiTroNew.sGhiChu;
                    objVaiTroOld.fk_iDonViID = _objVaiTroNew.fk_iDonViID;
                    objVaiTroOld.fk_iNguoiCapNhatID = _objVaiTroNew.fk_iNguoiCapNhatID;
                    objVaiTroOld.dNgayCapNhat = DateTime.Now;
                    db.SubmitChanges();
                    blnRes = true;
                    //Cập nhật danh sách quyền
                    UpdateDanhSachQuyen(_objVaiTroNew.pk_iVaiTroID, _dicQuyen);
                }
            }
            catch (Exception ex)
            {
                }
            db = null;
            return blnRes;
        }

        /// <summary>
        /// Xoa 
        /// </summary>
        /// <param name="_pk_iVaiTroID"></param>
        /// <returns></returns>
        public bool Delete(long _pk_iVaiTroID)
        {
            bool blnRes = false;
            db = new RBACDataContext(strConnectionString);
            try
            {
                List<tbl_VaiTro> LstVaiTroOld = (from m in db.tbl_VaiTros
                                                 where m.sPath.Contains(_pk_iVaiTroID.ToString())
                                                 select m).ToList<tbl_VaiTro>();
                if (LstVaiTroOld != null && LstVaiTroOld.Count > 0)
                {
                    foreach (tbl_VaiTro objVaiTroOld in LstVaiTroOld)
                    {
                        if (objVaiTroOld != null && objVaiTroOld.pk_iVaiTroID > 0)
                        {
                            objVaiTroOld.bKichHoat = false;
                            db.SubmitChanges();
                            blnRes = true;
                        }
                        if (blnRes == true)
                        {
                            var objQuyenVaiTro = from n in db.tbl_QuyenVaiTros
                                                 where n.fk_iVaiTroID == objVaiTroOld.pk_iVaiTroID
                                                 select n;
                            db.tbl_QuyenVaiTros.DeleteAllOnSubmit(objQuyenVaiTro);
                            db.SubmitChanges();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
               
            }
            db = null;
            return blnRes;
        }

        /// <summary>
        /// Lấy danh sách quyền
        /// </summary>
        /// <param name="_lngVaiTroID"></param>
        /// <returns></returns>
        public List<long> GetListCheckedQuyen(long _lngVaiTroID)
        {
            List<long> lstRes = null;
            RBACDataContext db = new RBACDataContext(strConnectionString);
            try
            {
                List<tbl_QuyenVaiTro> lstQuyen = (from t in db.tbl_QuyenVaiTros
                                                  where t.fk_iVaiTroID == _lngVaiTroID
                                                  select t).ToList<tbl_QuyenVaiTro>();
                if (lstQuyen != null && lstQuyen.Count > 0)
                {
                    lstRes = new List<long>();
                    foreach (tbl_QuyenVaiTro obj in lstQuyen)
                    {
                        lstRes.Add(obj.fk_iQuyenID);
                    }
                }
                lstQuyen = null;
            }
            catch (Exception ex)
            {
                
            }
            db = null;
            return lstRes;
        }

        /// <summary>
        /// Cập nhật danh sách quyền của vai trò
        /// Lấy danh sách quyền theo vai trò
        /// Nếu chưa có thì thêm vào
        /// Nếu đã tồn tại nhưng chưa có trong array thì xóa
        /// </summary>
        /// <param name="_lngVaiTroID"></param>
        /// <param name="dicQuyen"></param>
        /// <returns></returns>
        public bool UpdateDanhSachQuyen(long _lngVaiTroID, Dictionary<int, bool> dicQuyen)
        {
            bool blnRes = false;
            List<int> lstRemove = new List<int>();
            RBACDataContext db = new RBACDataContext(strConnectionString);
            tbl_QuyenVaiTro objQuyenVaiTro = null;
            try
            {
                List<tbl_QuyenVaiTro> lstQuyenVaiTro = (from t in db.tbl_QuyenVaiTros
                                                        where t.fk_iVaiTroID == _lngVaiTroID
                                                        select t).ToList<tbl_QuyenVaiTro>();
                if (lstQuyenVaiTro != null && lstQuyenVaiTro.Count > 0)
                {
                    foreach (tbl_QuyenVaiTro obj in lstQuyenVaiTro)
                    {
                        if (dicQuyen.ContainsKey(obj.fk_iQuyenID))
                        {
                            dicQuyen[obj.fk_iQuyenID] = true; //Đã tồn tại trong CSDL
                        }
                        else
                        {
                            lstRemove.Add(obj.fk_iQuyenID); //Them vao danh sach de xoa
                        }
                    }
                }
                //Begin transaction
                using (var trans = new TransactionScope())
                {
                    try
                    {
                        //Thêm lựa chọn mới vào danh sách
                        List<tbl_QuyenVaiTro> lstQuyenVaiTroAdd = new List<tbl_QuyenVaiTro>();
                        foreach (KeyValuePair<int, bool> obj in dicQuyen)
                        {
                            if (!obj.Value)
                            {
                                objQuyenVaiTro = new tbl_QuyenVaiTro();
                                objQuyenVaiTro.fk_iQuyenID = obj.Key;
                                objQuyenVaiTro.fk_iVaiTroID = _lngVaiTroID;
                                lstQuyenVaiTroAdd.Add(objQuyenVaiTro);
                            }
                        }
                        if (lstQuyenVaiTroAdd.Count > 0)
                        {
                            db.tbl_QuyenVaiTros.InsertAllOnSubmit(lstQuyenVaiTroAdd);
                            db.SubmitChanges();
                        }
                        //Xóa các lựa chọn đã bỏ check
                        List<tbl_QuyenVaiTro> lstQuyenVaiTroRemove = new List<tbl_QuyenVaiTro>();
                        foreach (int i in lstRemove)
                        {
                            try
                            {
                                objQuyenVaiTro = null;
                                objQuyenVaiTro = (from qv in db.tbl_QuyenVaiTros
                                                  where qv.fk_iQuyenID == i
                                                  && qv.fk_iVaiTroID == _lngVaiTroID
                                                  select qv).FirstOrDefault<tbl_QuyenVaiTro>();
                            }
                            catch (Exception ex)
                            {
                                
                            }
                            if (objQuyenVaiTro != null)
                            {
                                lstQuyenVaiTroRemove.Add(objQuyenVaiTro);
                            }
                        }
                        if (lstQuyenVaiTroRemove.Count > 0)
                        {
                            db.tbl_QuyenVaiTros.DeleteAllOnSubmit(lstQuyenVaiTroRemove);
                            db.SubmitChanges();
                        }
                        //Commit data
                        trans.Complete();
                    }
                    catch (Exception ex)
                    {
                        
                        trans.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                
            }
            db = null;
            return blnRes;
        }

        /// <summary>
        /// Thêm quyền vào vai trò
        /// </summary>
        /// <param name="_objQuyenVaiTro"></param>
        /// <returns></returns>
        public bool InsertQuyenVaiTro(tbl_QuyenVaiTro _objQuyenVaiTro)
        {
            bool blnRes = false;
            RBACDataContext db = new RBACDataContext(strConnectionString);
            try
            {
                tbl_QuyenVaiTro objQuyenVaiTroTmp = null;
                try
                {
                    objQuyenVaiTroTmp = (from t in db.tbl_QuyenVaiTros
                                         where t.fk_iQuyenID == _objQuyenVaiTro.fk_iQuyenID
                                         && t.fk_iVaiTroID == _objQuyenVaiTro.fk_iVaiTroID
                                         select t).FirstOrDefault<tbl_QuyenVaiTro>();

                }
                catch (Exception ex)
                {
                    
                }
                if (objQuyenVaiTroTmp != null)
                {
                    throw new ArgumentException("Quyền này đã có trong danh sách!");
                }
                else
                {
                    db.tbl_QuyenVaiTros.InsertOnSubmit(_objQuyenVaiTro);
                    db.SubmitChanges();
                    blnRes = true;
                }
            }
            catch (Exception ex)
            {
                
            }
            db = null;
            return blnRes;
        }//End InsertQuyenVaiTro

        /// <summary>
        /// Xóa quyền khỏi vai trò
        /// </summary>
        /// <param name="_objQuyenVaiTro"></param>
        /// <returns></returns>
        public bool RemoveQuyenVaiTro(tbl_QuyenVaiTro _objQuyenVaiTro)
        {
            bool blnRes = false;
            RBACDataContext db = new RBACDataContext(strConnectionString);
            try
            {
                tbl_QuyenVaiTro objQuyenVaiTroTmp = null;
                try
                {
                    objQuyenVaiTroTmp = (from t in db.tbl_QuyenVaiTros
                                         where t.fk_iQuyenID == _objQuyenVaiTro.fk_iQuyenID
                                         && t.fk_iVaiTroID == _objQuyenVaiTro.fk_iVaiTroID
                                         select t).FirstOrDefault<tbl_QuyenVaiTro>();
                    if (objQuyenVaiTroTmp != null)
                    {
                        db.tbl_QuyenVaiTros.DeleteOnSubmit(objQuyenVaiTroTmp);
                        db.SubmitChanges();
                        blnRes = true;
                    }
                    else
                    {
                        throw new ArgumentException("Quyền này không có trong danh sách!");
                    }
                }
                catch (Exception ex)
                {
                    
                    throw new ArgumentException("Quyền này không có trong danh sách!");
                }
            }
            catch (Exception ex)
            {
                
            }
            db = null;
            return blnRes;
        }//End RemoveQuyenVaiTro

        /// <summary>
        /// Cập nhật vai trò
        /// </summary>
        /// <param name="objVaiTro"></param>
        /// <param name="listQuyen"></param>
        /// <returns></returns>
        public bool UpdateVaiTro(tbl_VaiTro objVaiTro, string listQuyen)
        {
            bool Res = false;
            try
            {
                SqlParameter[] commandParameter = null;
                commandParameter = new SqlParameter[5];

                commandParameter[0] = new SqlParameter();
                commandParameter[0].ParameterName = "@in_vaiTroId";
                commandParameter[0].Value = objVaiTro.pk_iVaiTroID;

                commandParameter[1] = new SqlParameter();
                commandParameter[1].ParameterName = "@in_tenVaiTro";
                commandParameter[1].Value = objVaiTro.sTenVaiTro;

                commandParameter[2] = new SqlParameter();
                commandParameter[2].ParameterName = "@in_ghiChu";
                commandParameter[2].Value = objVaiTro.sGhiChu.ToString();

                commandParameter[3] = new SqlParameter();
                commandParameter[3].ParameterName = "@in_kieu";
                commandParameter[3].Value = objVaiTro.bDungChung;

                commandParameter[4] = new SqlParameter();
                commandParameter[4].ParameterName = "@in_danhSachQuyenId";
                commandParameter[4].Value = listQuyen;

                if (commandParameter != null)
                {
                    SqlHelper.ExecuteDataset(strConnectionString, "sp_CapNhatVaiTro", commandParameter);
                    Res = true;
                }
            }
            catch (Exception ex)
            {
                Res = false;
            }

            return Res;
        }
    }
}
